package com.warm.base.jdk.grammar;

import com.warm.common.entity.SysUser;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @Date: 2019/9/18 22:06
 * @Author: LChuang
 * @Description: Stream流
 */
public class StreamTest {

    public static void main(String[] args){
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(1);
        list.add(1);
        list.add(1);
        list.add(1);

        System.out.print("init:");
        for (Integer elem : list) {
            System.out.print(elem + "");
        }
        System.out.println();

        System.out.print("min:");
        Stream<Integer> stream = list.stream();
        Optional<Integer> min = stream.min(Integer::compareTo);
        if(min.isPresent()){
            System.out.println(min.get());
        }

        System.out.print("max:");
        list.stream().max(Integer::compareTo).ifPresent(System.out::println);

        System.out.print("sort:");
        Stream<Integer> sorted = list.stream().sorted();
        sorted.forEach(elem -> System.out.print(elem + " "));

        System.out.println();
        System.out.print("filter > 0, < 4 :");
        list.stream()
                .filter(elem -> elem > 0)
                .filter(elem -> elem < 4)
                //.sorted(Integer::compareTo)
                .forEach(System.out::print);
        System.out.println();
        System.out.print("source:");
        list.stream().forEach(elem -> System.out.print(elem + ""));

        List<Map<String, Object>> listMaps = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        map.put("a", 1);
        Map<String, Object> map1 = new HashMap<>();
        map1.put("a", 2);
        listMaps.add(map);
        listMaps.add(map1);
        List<Integer> ids = new ArrayList<>();

        listMaps.forEach(item->{
            item.forEach((k, v)->{
                ids.add((Integer) v);
            });
        });
        System.out.println(ids.size());
    }

    private static void optional(){
        SysUser i = new SysUser();
        Optional<Object> o = Optional.of(i);
        System.out.println(o.isPresent() ? o.get() : "-");

        List<Integer> list = Arrays.asList(2, 3, 4);
        Optional<Object> o1 = Optional.of(list);
        System.out.println(o1.isPresent()?o.get():"-");


    }

    private static void test(){
        List<Integer> ages = Arrays.asList(2, 3, 4);
        List<Integer> ages1 = Arrays.asList(1, 3);
        boolean isOk = ages1.stream().allMatch(a->ages.contains(a));
        System.out.println(isOk);
    }

    private static void predicate(String check){
        String value = "check";
        //judge true or false
        Predicate<String> predicate = x -> x.equals(value);
        System.out.println(check + " > 188 : " + predicate.test(check));
    }

    private static void consumer(String message){
        Consumer<String> consumer = System.out::println;
        consumer.accept("consumer message test!");
    }

    private static void function(SysUser sysUser){
        Function<SysUser, Integer> function = SysUser::getAge;
        Integer age = function.apply(sysUser);
        System.out.println(age);
    }

    private static void removeDupl(){
        SysUser user1 = new SysUser();
        SysUser user2 = new SysUser();
        SysUser user3 = new SysUser();
        SysUser user4 = new SysUser();
        user1.setAge(9);
        user2.setAge(10);
        user3.setAge(11);
        user4.setAge(12);
        List<SysUser> list = new ArrayList<>();
        list.add(user1);
        list.add(user2);
        list.add(user3);
        list.add(user4);
        list.add(user1);
        list.add(user2);

        List<Integer> ages = list.stream().map(SysUser::getAge).distinct().collect(Collectors.toList());
        ages.forEach(age->{
            System.out.println(age);
        });

        // 使用TreeSet去重
        List<SysUser> dptList = list.stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(
                        () -> new TreeSet<>(Comparator.comparing(o -> o.getAge()))
                ), ArrayList::new)
        );

        List<SysUser> distinctError = list.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(
                                Comparator.comparing(o -> o.getAge() + ";" + o.getAccount()))
                        ), ArrayList::new));
        //使用map去重
        List<SysUser> unique2 = list.stream()
                .filter(distinctByKey(o -> o.getId()))
                .collect(Collectors.toList());
        System.out.println(unique2);

        dptList.forEach(user->System.out.println(user.getAge()));

        Map<Integer, List<SysUser>> dptList1 = list.stream().collect(
                Collectors.groupingBy(item->item.getAge()));

        dptList1.forEach((k, v)->{
            System.out.println(v);
        });

        List<SysUser> dptList3 = list.stream().distinct().collect(Collectors.toList());
        dptList3.forEach(user->System.out.println(user.getAge()));

        List<Integer> sortAges = list.stream()
                .filter(u -> u.getAge() >= 10)
                .sorted(Comparator.comparing(SysUser::getAge).reversed())
                .map(SysUser::getAge)
                .collect(Collectors.toList());
        System.out.println("-----------------");
        sortAges.forEach(System.out::println);
    }
    public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        System.out.println("这个函数将应用到每一个item");
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    private static void intStream(){
        IntStream.of(new int[]{1, 2, 3}).forEach(System.out::println);
        IntStream.range(1, 2);
    }
}
